﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DotVVM.BusinessPack.Controls;
using DotVVM.Framework.Hosting;
using DotVVM.Framework.Storage;
using DotVVM.Framework.ViewModel;
using VOICeVIO.Hybrid.Models;
using VOICeVIO.Hybrid.Services;

//MIME: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-2.1&tabs=aspnetcore2x

namespace VOICeVIO.Hybrid.ViewModels
{
    public class CreateViewModel : MasterPageViewModel
    {
        [Bind(Direction.ServerToClientFirstRequest)]
        public List<SvssSinger> Singers { get; set; } = new List<SvssSinger>()
        {
            new SvssSinger {Name = "謡子（Yoko/f001）", SingerType = Singer.Yoko},
            new SvssSinger {Name = "謡君（Yokun/m001）", SingerType = Singer.Yokun},
            new SvssSinger {Name = "すずきつづみ[冷]（Tsudumi/f802-cool）",SingerType = Singer.TsudumiCool},
            new SvssSinger {Name = "すずきつづみ[照]（Tsudumi/f802-bashful）",SingerType = Singer.TsudumiBashful},
        };

        private const string TooMuchUpload = "You have uploaded too much projects today. Please come back tomorrow.";
        public int UploadLimitation = 20;
        //public string ProcessState { get; set; } = "Processing...";
        public bool UploadFinished { get; set; } = false;
        //public UploadedFilesCollection UploadedFiles { get; set; }
        public UploadData UploadedFiles { get; set; } = new UploadData();
        public SongDetailModel Song { get; set; } = new SongDetailModel { CreateTime = DateTime.Now, Uid = Guid.NewGuid().ToString("N") };
        public string Hint { get; set; } = "Please upload file.";
        private string _ccsPath = "ccs";
        private readonly IUploadedFileStorage _storage;

        private readonly HybridService _hybridService;

        public CreateViewModel(HybridService hybridService, IUploadedFileStorage storage)
        {
            _hybridService = hybridService;
            _storage = storage;
        }

        public override async Task PreRender()
        {
            var count = await _hybridService.GetUploadCountAsync(Context.GetAspNetCoreContext().GetClientIP());
            if (count > UploadLimitation)
            {
                Hint = TooMuchUpload;
            }
            else
            {
                Hint = $"You can upload {UploadLimitation - count} projects today.";
            }
            await base.PreRender();
        }

        public async Task ProcessFile()
        {
            Hint = "";
            if (UploadedFiles.Files.Count <= 0)
            {
                return;
            }
            var count = await _hybridService.GetUploadCountAsync(Context.GetAspNetCoreContext().GetClientIP());
            if (count > UploadLimitation)
            {
                Hint = TooMuchUpload;
            }

            var file = UploadedFiles.Files.LastOrDefault(f => f.IsAllowed);
            
            if (file == null)
            {
                Hint = "This file is not allowed.";
                return;
            }

            if (file.FileName == "demo.ccs" || file.FileName == "demo.xml")
            {
                Song.Singer = Singer.TsudumiCool;
            }

            //if (Uploaded == null || !Uploaded.IsAllowed)
            //{
            //    return;
            //}
            //var file = Uploaded;

            // get the stream of the uploaded file and do whatever you need to do
            var fileStream = _storage.GetFile(file.FileId);
            var hash = Helper.GetMd5(fileStream);
            fileStream.Dispose();

            if (hash == "168C99E995488A42D84A3AE81B24FFF4")
            {
                Song.SongName = "虹色蝶々";
                Song.Author = "黒うさＰ";
                Song.Note = "CCS made by Ulysses";
            }
            //var s = await _hybridService.GetSongByHashAsync(hash);
            //if (s != null)
            //{
            //    return;
            //}

            Song.ProjectHash = hash;
            if (!Directory.Exists(_ccsPath))
            {
                Directory.CreateDirectory(_ccsPath);
            }

            var projectPath = Path.Combine(_ccsPath, Song.Uid + ".ccs");
            _storage.SaveAs(file.FileId, projectPath);
            UploadFinished = true;
            // OR you can just move the file from the temporary storage somewhere else
            //var targetPath = Path.Combine(uploadPath, file.FileId + ".bin");
            //storage.SaveAs(file.FileId, targetPath);

            // it is a good idea to delete the file from the temporary storage 
            // it is not required, the file would be deleted automatically after the timeout set in the DotvvmStartup.cs
            //storage.DeleteFile(file.FileId);
        }
        
        public async Task AddSong()
        {
            var s = await _hybridService.GetSongByUidAsync(Song.Uid);
            if (s != null)
            {
                Hint = "This song has been uploaded before, try another file.";
                return;
            }

            var ip = Context.GetAspNetCoreContext().GetClientIP();
            var count = await _hybridService.GetUploadCountAsync(ip);
            if (count > UploadLimitation)
            {
                Hint = TooMuchUpload;
                return;
            }
            Song.IP = ip;
            await _hybridService.InsertSongAsync(Song);
            Context.RedirectToRoute("Download", new { Id = Song.Uid, Name = Song.SongName });
        }
    }
}
